#include "helper/sqlite/detail/Statement.h"

#include <cassert>
#include <sqlite3.h>

namespace helper {
namespace sqlite {
namespace detail {

Statement::Statement(sqlite3_stmt * stmt)
: _stmt(stmt)
{
}
Statement::~Statement(){
  if(_stmt != nullptr){
    assert(0 == sqlite3_finalize(_stmt));
		_stmt = nullptr;
  }
}
int Statement::step(){
  assert(_stmt != 0);
  return sqlite3_step(_stmt);
}
int Statement::reset() {
  assert(_stmt != 0);
  return sqlite3_reset(_stmt);
}

int Statement::clearBindings(){
  assert(_stmt != 0);
  return sqlite3_clear_bindings(_stmt);
}

int Statement::bindInteger(int index, int64_t value){
  assert(_stmt != 0);
  return sqlite3_bind_int(_stmt, index, value);
}

int Statement::bindDouble(int index, double value){
  assert(_stmt != 0);
  return sqlite3_bind_double(_stmt, index, value);
}
int Statement::bindText(int index, const char * str, int64_t len){
  assert(_stmt != 0);
  return sqlite3_bind_text64(_stmt, index, str, len, SQLITE_STATIC, SQLITE_UTF8);
}

int Statement::bindText(int index, const std::string & str){
  assert(_stmt != 0);
  return sqlite3_bind_text64(_stmt, index, str.c_str(), str.length(), SQLITE_STATIC, SQLITE_UTF8);
}
int Statement::bindBlob(int index, const char * bin, int64_t len){
  assert(_stmt != 0);
  return sqlite3_bind_blob64(_stmt, index, (const void *)bin, len, SQLITE_STATIC);
}
int Statement::bindBlob(int index, const std::string & bin){
  assert(_stmt != 0);
  return sqlite3_bind_blob64(_stmt, index, (const void *)bin.c_str(), bin.length(), SQLITE_STATIC);
}
int Statement::bindZeroBlob(int index, int64_t len){
  assert(_stmt != 0);
  return sqlite3_bind_zeroblob64(_stmt, index, len);
}
int Statement::bindNull(int index){
  assert(_stmt != 0);
  return sqlite3_bind_null(_stmt, index);
}

int64_t  Statement::columnInteger(int index) const{
  assert(_stmt != 0);
  return sqlite3_column_int64(_stmt, index);
}
double  Statement::columnDouble(int index) const{
  assert(_stmt != 0);
  return sqlite3_column_double(_stmt, index);
}
const unsigned char * Statement::columnText(int index) const{
  assert(_stmt != 0);
  return sqlite3_column_text(_stmt, index);
}
int Statement::columnType(int index) const{
  assert(_stmt != 0);
  return sqlite3_column_type(_stmt, index);
}
int Statement::columnBytes(int index) const{
  assert(_stmt != 0);
  return sqlite3_column_bytes(_stmt, index);
}
int Statement::columnCount() const {
  assert(_stmt != 0);
	return sqlite3_column_count(_stmt);
}
const char * Statement::columnName(int index) const {
  assert(_stmt != 0);
	return sqlite3_column_name(_stmt, index);
}
/*  
const char * Statement::columnOriginName(int index) const{
  assert(_stmt != 0);
	return sqlite3_column_origin_name(_stmt, index);
}
const char * Statement::columnDatabaseName(int index) const{
  assert(_stmt != 0);
	return sqlite3_column_database_name(_stmt, index);
}
const char * Statement::columnTableName(int index) const{
  assert(_stmt != 0);
	return sqlite3_column_table_name(_stmt, index);
}
*/
const char * Statement::columnDeclareType(int index) const{
  assert(_stmt != 0);
	return sqlite3_column_decltype(_stmt, index);
}
sqlite3 * Statement::dbHandler() const{
  assert(_stmt != 0);
	return sqlite3_db_handle(_stmt);	
}

const char * Statement::sql() const{
  assert(_stmt != 0);
	return sqlite3_sql(_stmt);
}
char * Statement::expandedSql() const{
  assert(_stmt != 0);
	return sqlite3_expanded_sql(_stmt); 
}
bool Statement::isBusy() const{
  assert(_stmt != 0);
	return sqlite3_stmt_busy(_stmt) != 0;
}
bool Statement::isExplain() const{
  assert(_stmt != 0);
	return sqlite3_stmt_isexplain(_stmt) != 0;
}
bool Statement::isReadOnly() const{
  assert(_stmt != 0);
	return sqlite3_stmt_readonly(_stmt) != 0;
}
void * Statement::raw() const {
  assert(_stmt != 0);
  return _stmt;
}

}//namespace detail
}//namespace sqlite
}//namespace helper
